package com.llb.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName AnnotationUtils
 * @Description TODO
 * @Author liang
 * @Date 2019/3/22 22:27
 * @Version 1.0
 **/
public class AnnotationUtils {
    //缓存,  (对象1 , (对象1,属性列表))
    private static final Map<Class<?>, Map<Class<?>, List<Field>>> ANNOTATION_FIELD_CACHE_MAP = new ConcurrentHashMap();


    public static List<Field> getAnnotationFieldsInClass(Class<? extends Annotation> annotation, Class<?> targetClass) {
        //判断此对象是否已经在map中,没有则put一个
        if (ANNOTATION_FIELD_CACHE_MAP.get(targetClass) != null) {
            if (((Map)ANNOTATION_FIELD_CACHE_MAP.get(targetClass)).get(annotation) != null) {
                return (List)((Map)ANNOTATION_FIELD_CACHE_MAP.get(targetClass)).get(annotation);
            }
        } else {
            Map<Class<?>, List<Field>> annotationMap = new HashMap();
            ANNOTATION_FIELD_CACHE_MAP.put(targetClass, annotationMap);
        }

        List<Field> annotationFieldList = new ArrayList();
        //将注解属性放入list中
        findAnnotationField(annotationFieldList, annotation, targetClass);
        //放入map中
        ((Map)ANNOTATION_FIELD_CACHE_MAP.get(targetClass)).put(annotation, annotationFieldList);
        return annotationFieldList;
    }

    private static void findAnnotationField(List<Field> resultList, Class<? extends Annotation> annotation, Class<?> targetClass) {
        Field[] arr = targetClass.getDeclaredFields();
        int len = arr.length;

        for(int i = 0; i < len; ++i) {
            Field field = arr[i];
            if (field.isAnnotationPresent(annotation)) {
                resultList.add(field);
            }
        }

        if (targetClass.getSuperclass() != null && targetClass.getSuperclass() != Object.class) {
            findAnnotationField(resultList, annotation, targetClass.getSuperclass());
        }

    }
}
